package com.tensquare.notice.netty;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.tensquare.entity.Result;
import com.tensquare.entity.StatusCode;
import com.tensquare.notice.config.ApplicationContextProvider;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.rabbit.listener.SimpleMessageListenerContainer;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

public class MyWebSocketHandler extends SimpleChannelInboundHandler<TextWebSocketFrame> {

    private static ObjectMapper MAPPER = new ObjectMapper();

    public static ConcurrentHashMap<String, Channel> userChannelMap = new ConcurrentHashMap<>();

    //从容其中获取rabbitTemplate
    RabbitTemplate rabbitTemplate = ApplicationContextProvider.getApplicationContext().getBean(RabbitTemplate.class);
    //从容其中获取消息监听器,处理订阅消息SYSNotice
    SimpleMessageListenerContainer sysNoticeContainer = (SimpleMessageListenerContainer) ApplicationContextProvider.getApplicationContext().getBean("sysNoticeContainer");
    //从容其中获取消息监听器,处理点赞消息USERNotice
    SimpleMessageListenerContainer userNoticeContainer = (SimpleMessageListenerContainer) ApplicationContextProvider.getApplicationContext().getBean("userNoticeContainer");


    //用户请求websocket服务端,执行的方法
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, TextWebSocketFrame msg) throws Exception {
        //约定用户第一次请求时携带的数据 带有  userid
        //获取请求并接解析
        String text = msg.text();
        String userId = MAPPER.readTree(text).get("userId").asText();

        //第一次连接,建立websocket连接
        Channel channel = userChannelMap.get(userId);
        if (channel == null) {
            //不存在即可建立连接
            channel = ctx.channel();
            //连接放到容器中
            userChannelMap.put(userId, channel);
        }

        //完成新消息的提醒即可,只需要获取消息的数量
        //获取RabbitMQ订阅消息内容并发送给用户
        RabbitAdmin rabbitAdmin = new RabbitAdmin(rabbitTemplate);
        String queueName = "article_subscribe_" + userId;
        Properties queueProperties = rabbitAdmin.getQueueProperties(queueName);
        //获取消息数量
        int noticeCount = 0;
        if (queueProperties != null) {
            noticeCount = (int) queueProperties.get("QUEUE_MESSAGE_COUNT");
        }

        //获取RabbitMQ点赞消息内容并发送给用户
        String userQueueName = "article_thumbup_" + userId;
        Properties userQueueProperties = rabbitAdmin.getQueueProperties(userQueueName);
        //获取消息数量
        int userNoticeCount = 0;
        if (userQueueProperties != null) {
            userNoticeCount = (int) userQueueProperties.get("QUEUE_MESSAGE_COUNT");
        }


        //封装数据
        Map countMap = new HashMap();
        countMap.put("sysNoticeCount", noticeCount);
        countMap.put("userNoticeCount", userNoticeCount);
        Result result = new Result(true, StatusCode.OK, "查询消息成功", countMap);

        //数据发送给用户
        channel.writeAndFlush(new TextWebSocketFrame(MAPPER.writeValueAsString(result)));

        //查询后清空消息队列
        if (noticeCount > 0) {
            rabbitAdmin.purgeQueue(queueName, true);
        }
        if (noticeCount > 0) {
            rabbitAdmin.purgeQueue(userQueueName, true);
        }


        sysNoticeContainer.addQueueNames(queueName);
        userNoticeContainer.addQueueNames(userQueueName);

    }
}
